package plgbasev0

import (
	"dgo/goutils/utils"
	"fmt"
	"gitee.com/ymofen/gobase/golog"
	"gitee.com/ymofen/supervalue"
	"strings"
)

type InnerInput struct {
	Name       string
	LogTypeStr string

	ex          interface{}
	ex_id       string
	topic       string // 订阅数据topic
	templ       string
	ReleaseFlag int
}

func NewInnerInput() *InnerInput {
	return &InnerInput{}
}

func (this *InnerInput) Release() {
	this.innerProcessPre()
	this.ReleaseFlag = 1
}

func (this *InnerInput) Valid() bool {
	return this.ex != nil
}

func (this *InnerInput) String() string {
	return fmt.Sprintf("InnerInput-%p-%s", this, this.Name)
}

func (this *InnerInput) innerProcessPre() {
	if this.ex != nil && len(this.topic) > 0 {
		if sc, ok := this.ex.(utils.IUnSubscribe); ok {
			strs := strings.Split(this.topic, ",")
			for _, v := range strs {
				sc.UnsubscribeChannel(utils.Trim(v), this)
			}
		} else if sc := GetSubscribeFromVal(this.ex); sc != nil {
			if this.topic == "*" {
				sc.UnSubscribeAllChannel(this)
			} else {
				strs := strings.Split(this.topic, ",")
				for _, v := range strs {
					sc.UnsubscribeChannel(utils.Trim(v), this)
				}
			}
			this.topic = ""
		}
	}
}

/*
*

	{
	    "id":"ex",
	    "topic":"xxxx"
	 }
*/
func (this *InnerInput) ReloadConf(conf *wrapper.SuperValue, onInput utils.SubscribeCallback) (err error) {

	if conf == nil {
		return
	}

	conf.CheckExistsStrFunc("templ", func(strv string) {
		this.templ = strv
	})

	return this.Config(conf.StringByName("id", ""), conf.StringByName("topic", ""), onInput)
}

func (this *InnerInput) Config(id, topic string, onInput utils.SubscribeCallback) (err error) {

	ischanged := false

	var unsubprefn = this.innerProcessPre

	if len(id) > 0 {
		if this.ex_id != id {
			unsubprefn()
			this.ex = nil

			ex := FindPluginByID(id)
			if ex == nil {
				golog.Warnf("[%s]not found!", id)
				return
			}
			this.ex = ex
			ischanged = true
		}

	}

	if len(topic) > 0 {
		if this.topic != topic {
			unsubprefn()
			this.topic = topic
		}
	}

	if ischanged {
		if len(this.topic) > 0 && this.ex != nil {
			if sc, ok := this.ex.(utils.ISubscribe); ok {
				strs := strings.Split(this.topic, ",")
				for _, v := range strs {
					sc.SubscribeChannel(utils.Trim(v), this, onInput)
				}
			} else if sc := GetSubscribeFromVal(this.ex); sc != nil {
				if this.topic == "*" {
					sc.SubscribeAllChannel(this, onInput)
				} else {
					strs := strings.Split(this.topic, ",")
					for _, v := range strs {
						sc.SubscribeChannel(utils.Trim(v), this, onInput)
					}
				}
			}
		}
	}
	return
}

func (this *InnerInput) SendTopic(topic string, json *wrapper.SuperValue) {
	if this.ReleaseFlag == 1 {
		return
	}

	ex := this.ex
	if ex == nil {
		return
	}
	if sc, ok := ex.(IDispatchData); ok {
		err := sc.DispatchData(topic, this, json, nil)
		if err != nil {
			golog.Warnf("[%s]分发数据出现异常:%s", this.LogTypeStr, err.Error())
		}
	} else if sc, ok := ex.(ISendKVs); ok {
		err := sc.SendKVs(topic, json)
		if err != nil {
			golog.Warnf("[%s]分发数据出现异常:%s", this.LogTypeStr, err.Error())
		}
	} else {
		golog.Warnf("发送插件不支持ISendKVs")
	}
}

func (this *InnerInput) SendTopicFunc(topic string, fillStatus func(json *wrapper.SuperValue)) {
	ex := this.ex
	if ex == nil {
		return
	}
	json := wrapper.NewSVObject()
	if len(this.templ) > 0 {
		json.JsonParserFromByte([]byte(this.templ))
	}
	fillStatus(json)
	this.SendTopic(topic, json)
}
